package com.cmii.sjw.department.control.jsc.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cmii.sjw.department.control.jsc.mapper.ActivityCodeMapper;
import com.cmii.sjw.department.control.jsc.mapper.SsoActivityMapper;
import com.cmii.sjw.department.control.jsc.model.ActivityCode;
import com.cmii.sjw.department.control.jsc.model.SsoActivity;
import com.cmii.sjw.department.control.jsc.model.dto.ReportActivityDTO;
import com.cmii.sjw.department.control.jsc.model.params.EventReceiverParams;
import com.cmii.sjw.department.control.jsc.model.params.MultiSpanEventReceiverParams;
import com.cmii.sjw.department.control.jsc.service.IJyzzService;
import com.cmii.sjw.department.control.jsc.util.Result;
import com.cmii.sjw.department.control.jsc.util.RsaSignUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.utils.URIBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URISyntaxException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.List;


/**
 * @Author jfh
 * @Date 2024-11-12 周二 16:04
 * @Version 1.0
 */
@Slf4j
@Service
public class JyzzserviceImpl implements IJyzzService {


    @Autowired
    private SsoActivityMapper ssoActivityMapper;

    @Autowired
    private ActivityCodeMapper activityCodeMapper;

    /**
     * 事件数量统计
     *
     * @param appCode
     * @return
     */
    @Override
    public Result totalStatistics(String appCode) {

        JSONObject postData = new JSONObject()
                .fluentPut("appCode", appCode);
        log.info("postData:{}", postData.toJSONString());

        String apiResult = HttpUtil.createPost("http://23.210.23.1:6668/extapi/jyzz/total-statistics")
                .header(Header.CONTENT_TYPE, "application/json")
                .body(postData.toJSONString())
                .execute()
                .body();
        log.info("事件数量统计信息 postData:{}, apiResult:{}", postData, apiResult);
        com.alibaba.fastjson2.JSONObject content = com.alibaba.fastjson2.JSON.parseObject(apiResult);
        if ("200".equals(content.getObject("code", String.class))) {
            log.info("事件数量统计结果:{}", content.getString("data"));
            return Result.success(content.getObject("data", Object.class));
        } else {
            log.error("事件数量统计结果异常 responseCode:{} responseMessage:{}", content.getString("code"), content.getString("msg"));
            return Result.error(content.getString("msg"));
        }
    }

    /**
     * 多跨事件列表信息-倒排序
     *
     * @param appCode
     * @param pageSize
     * @param pageNum
     * @return
     */
    @Override
    public Result eventDetails(String appCode, Integer pageSize, Integer pageNum, String zoningCode) {

        String url = UriComponentsBuilder.fromHttpUrl("http://23.210.23.1:6668/extapi/jyzz/event-details")
                .queryParam("pageSize", pageSize)
                .queryParam("pageNum", pageNum)
//                .queryParam("zoningCode", zoningCode)
                .build()
                .toUriString();

        JSONObject postData = new JSONObject()
                .fluentPut("appCode", appCode)
                .fluentPut("zoningCode", zoningCode);
        log.info("postData:{},url:{}", postData.toJSONString(), url);

        String apiResult = HttpUtil.createPost(url)
                .header(Header.CONTENT_TYPE, "application/json")
                .body(postData.toJSONString())
                .execute()
                .body();
        log.info("多跨事件列表信息-倒排序 postData:{}, apiResult:{}", postData, apiResult);
        com.alibaba.fastjson2.JSONObject content = com.alibaba.fastjson2.JSON.parseObject(apiResult);
        if ("200".equals(content.getObject("code", String.class))) {
            log.info("多跨事件列表信息-倒排序结果:{}", content.getString("rows"));
            return Result.success(content.getObject("rows", Object.class));
        } else {
            log.error("多跨事件列表信息-倒排序结果异常 responseCode:{} responseMessage:{}", content.getString("code"), content.getString("msg"));
            return Result.error(content.getString("msg"));
        }
    }

    /**
     * 多跨事件详情查询接口
     *
     * @param eventType
     * @param eventNum
     * @return
     */
    @Override
    public Result eventInfo(String eventType, String eventNum) {

        String url = UriComponentsBuilder.fromHttpUrl("http://23.210.23.1:6668/extapi/jyzz/event-info")
                .queryParam("pageSize", 5)
                .queryParam("pageNum", 1)
                .build()
                .toUriString();

        JSONObject postData = new JSONObject()
                .fluentPut("eventType", eventType)
                .fluentPut("eventNum", eventNum);
        log.info("多跨事件详情查询 postData:{},url:{}", postData.toJSONString(), url);

        String apiResult = HttpUtil.createPost(url)
                .header(Header.CONTENT_TYPE, "application/json")
                .body(postData.toJSONString())
                .execute()
                .body();
        log.info("多跨事件详情查询 postData:{},apiResult:{}", postData, apiResult);
        com.alibaba.fastjson2.JSONObject content = com.alibaba.fastjson2.JSON.parseObject(apiResult);
        if ("200".equals(content.getObject("code", String.class))) {
            log.info("多跨事件详情查询结果:{}", content.getString("data"));
            return Result.success(content.getObject("data", Object.class));
        } else {
            log.error("多多跨事件详情查询异常 responseCode:{} responseMessage:{}", content.getString("code"), content.getString("msg"));
            return Result.error(content.getString("msg"));
        }
    }

    /**
     * 高校日活跃度
     */
    @Override
    public Result sso(ReportActivityDTO dto) {
        /*// 1. 时间戳校验（允许5分钟误差）
        long now = System.currentTimeMillis();
        if (Math.abs(now - timestamp) > 1000 * 60 * 15) {
            return Result.error("请求超时");
        }*/

        //log.info("Timestamp difference: " + Math.abs(now - timestamp));

        String organizationName = dto.getOrganizationName();
        String applicationSystemName = dto.getApplicationSystemName();
        Integer monthActivityUserNum = dto.getMonthActivityUserNum();
        Integer monthTargetUserNum = dto.getMonthTargetUserNum();
        Integer monthDoneEventNum = dto.getMonthDoneEventNum();
        String sign = dto.getSignContent();
        //long timestamp = dto.getReportTime();

        try {
            ActivityCode activityCode = activityCodeMapper.selectOne(
                    Wrappers.<ActivityCode>lambdaQuery()
                            .eq(ActivityCode::getSchoolName, organizationName)
                            .eq(ActivityCode::getApplicationSystemName, applicationSystemName)
                            .eq(ActivityCode::getIsDeleted, 0)
            );

            if (activityCode == null || StrUtil.isBlank(activityCode.getAuthCode())) {
                return Result.error("授权码不存在或已失效");
            }

            String authCode = activityCode.getAuthCode();
            // 2. 拼接待签名字符串
            String data = "authCode=" + authCode
                    + "&organizationName=" + organizationName
                    + "&applicationSystemName=" + applicationSystemName
                    + "&monthActivityUserNum=" + monthActivityUserNum
                    + "&monthTargetUserNum=" + monthTargetUserNum
                    + "&monthDoneEventNum=" + monthDoneEventNum;

            // 3. 用公钥解密前端传过来的 sign
            boolean verify = RsaSignUtil.verifySignature(data, sign);

            if (!verify) {
                log.info("签名验证失败！");
                return Result.error("签名验证失败");
            }
            log.info("签名验证成功！");

            // 4. 判断是新增还是更新（按“当前年月”判断）
            LocalDateTime nowTime = LocalDateTime.now();
            int nowYear = nowTime.getYear();
            int nowMonth = nowTime.getMonthValue();

            // 查询当前组织+系统的历史记录
            List<SsoActivity> activities = ssoActivityMapper.selectList(
                    Wrappers.<SsoActivity>lambdaQuery()
                            .eq(SsoActivity::getOrganizationName, organizationName)
                            .eq(SsoActivity::getApplicationSystemName, applicationSystemName)
                            .eq(SsoActivity::getIsDeleted, 0)
            );

            SsoActivity matchedActivity = null;
            for (SsoActivity a : activities) {
                LocalDateTime reportTime = a.getReportTime();
                if (reportTime != null && reportTime.getYear() == nowYear && reportTime.getMonthValue() == nowMonth) {
                    matchedActivity = a;
                    break;
                }
            }

            if (matchedActivity == null) {
                // 当前月份还没有记录，新增一条
                SsoActivity newActivity = new SsoActivity()
                        .setOrganizationName(organizationName)
                        .setApplicationSystemName(applicationSystemName)
                        .setMonthActivityUserNum(monthActivityUserNum)
                        .setMonthTargetUserNum(monthTargetUserNum)
                        .setMonthDoneEventNum(monthDoneEventNum)
                        .setIsDeleted(0)
                        .setCreateTime(nowTime)
                        .setUpdateTime(nowTime)
                        .setReportTime(nowTime);
                ssoActivityMapper.insert(newActivity);
            } else {
                // 当前月已有记录，更新
                matchedActivity.setMonthActivityUserNum(monthActivityUserNum);
                matchedActivity.setMonthTargetUserNum(monthTargetUserNum);
                matchedActivity.setMonthDoneEventNum(monthDoneEventNum);
                matchedActivity.setUpdateTime(nowTime);
                matchedActivity.setReportTime(nowTime);
                ssoActivityMapper.updateById(matchedActivity);
            }

            log.info("上报成功！");
            return Result.success("上报成功");
        } catch (Exception e) {
            log.error("sso 上报过程发生异常", e);
            return Result.error("内部异常: " + e.getMessage());
        }
    }

    /**
     * 第三方自闭环事件推送接口
     * @param params 第三方自闭环事件推送接口
     * @return 第三方自闭环事件推送接口
     */
    @Override
    public Result eventReceiver(EventReceiverParams params) {
        String url = UriComponentsBuilder.fromHttpUrl("http://23.210.23.1:6668/extapi/jyzz/event-receiver")
                .build()
                .toUriString();
        //params对象参数转成json
        String postData = JSONObject.toJSONString(params);

        String apiResult = HttpUtil.createPost(url)
                .header(Header.CONTENT_TYPE, "application/json")
                .body(postData)
                .execute()
                .body();
        log.info("第三方自闭环事件推送 postData:{},apiResult:{}", postData, apiResult);
        com.alibaba.fastjson2.JSONObject content = com.alibaba.fastjson2.JSON.parseObject(apiResult);
        if ("200".equals(content.getObject("code", String.class))) {
            log.info("第三方自闭环事件推送:{}", content.getString("data"));
            return Result.success(content.getObject("data", Object.class));
        } else {
            log.error("第三方自闭环事件推送异常 responseCode:{} responseMessage:{}", content.getString("code"), content.getString("msg"));
            return Result.error(content.getString("msg"));
        }
    }

    /**
     * 第三方多跨事件推送
     * @param params 多跨事件推送
     * @return 多跨事件推送
     */
    @Override
    public Result multiSpanEventReceiver(MultiSpanEventReceiverParams params) {
        String url = UriComponentsBuilder.fromHttpUrl("http://23.210.23.1:6668/extapi/jyzz/multi-span-event-receiver")
                .build()
                .toUriString();
        //params对象参数转成json
        String postData = JSONObject.toJSONString(params);

        String apiResult = HttpUtil.createPost(url)
                .header(Header.CONTENT_TYPE, "application/json")
                .body(postData)
                .execute()
                .body();
        log.info("第三方多跨事件推送 postData:{},apiResult:{}", postData, apiResult);
        com.alibaba.fastjson2.JSONObject content = com.alibaba.fastjson2.JSON.parseObject(apiResult);
        if ("200".equals(content.getObject("code", String.class))) {
            log.info("第三方多跨事件推送:{}", content.getString("data"));
            return Result.success(content.getObject("data", Object.class));
        } else {
            log.error("第三方多跨事件推送异常 responseCode:{} responseMessage:{}", content.getString("code"), content.getString("msg"));
            return Result.error(content.getString("msg"));
        }
    }

    /**
     * 按事件类型获取绑定角色帐户id
     * @param eventType 事件类型
     * @param belongCounty 所属县
     * @return 按事件类型获取绑定角色帐户id
     */
    @Override
    public Result<List<String>> getBindingRoleAccountIdByventType(String eventType, String belongCounty) {
        URIBuilder uriBuilder = null;
        try {
            // 【优化】从配置文件加载基础URL（假设已通过@Value注入）
            String baseUrl = "http://23.210.23.1:8081/smart_edu_gov/sjtb/getBindingRoleAccountIdByventType";
            uriBuilder = new URIBuilder(baseUrl);
            uriBuilder.addParameter("eventType", eventType);
            uriBuilder.addParameter("belongCounty", belongCounty);
            String url = uriBuilder.build().toString();

            log.info("按事件类型获取绑定角色帐户id-url: {}", url.replace(eventType, "***").replace(belongCounty, "***")); // 【安全】隐藏敏感字段

            // 【优化】添加超时控制
            String apiResult = HttpUtil.createPost(url)
                    .timeout(5000) // 设置5秒超时
                    .execute()
                    .body();

            log.debug("apiResult: {}", apiResult); // debug级别输出完整响应

            JSONObject response = JSON.parseObject(apiResult);

            // 【优化】加强空值判断
            if (response == null || !"200".equals(response.getString("code"))) {
                String msg = response != null ? response.getString("msg") : "未知错误";
                return Result.error("按事件类型获取绑定角色帐户id失败: " + msg);
            }

            JSONArray dataArray = response.getJSONArray("data");
            if (dataArray == null) {
                return Result.success(Collections.emptyList());
            }

            List<String> accountIds = JSON.parseArray(dataArray.toJSONString(), String.class);
            return Result.success(accountIds);

        } catch (URISyntaxException e) {
            log.error("构造URI失败，eventType={}, belongCounty={}", eventType, belongCounty, e);
            throw new IllegalArgumentException("无效的请求参数", e); // 【改进】使用更具语义的异常类型
        }
    }
}
